#ifndef _H_TYPEDEF_H_
#define _H_TYPEDEF_H_
// 主体类型

// 导出导入符号
#ifdef _M_OS_WIN
#   define Export __declspec(dllexport)
#   define Import __declspec(dllimport)
#elif defined(_M_OS_LINUX)
#   define Export __attribute__((visibility("default")))
#   define Import
#endif

#ifdef _M_INTERNAL
#   define Export
#endif

// 核心类型头
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

#define true 1  // 逻辑假
#define false 0 // 逻辑假
#define not -1  // 逻辑未知，实际上也为逻辑真，仅用作状态标志

    // 三值类型（真、假、未知）
typedef signed char terval;

//#ifndef __cplusplus
    typedef unsigned char byte;
//#endif // __cplusplus

typedef signed char sbyte;
typedef signed char int8, t_i1;
typedef signed short int16, t_i2;
typedef signed int int32, t_i4;
typedef signed long long int64, t_i8;
typedef unsigned char uint8, t_u1;
typedef unsigned short uint16, t_u2;
typedef unsigned int uint32, t_u4;
typedef unsigned long long uint64, t_u8;
typedef float float32, t_f4;
typedef double float64, t_f8;
// C字符串类型
typedef unsigned char *cstring;

// 指针类型
typedef void *ptr;
// 空指针
#define null ((ptr)0)

//#ifndef __cplusplus
    // 逻辑类型
    typedef signed char bool;
//#endif

#ifdef _M_OS_WIN
    // 字符串类型
    typedef uint16 *string;
    // 宽字符类型
    typedef uint16 wchar;
#   define ENCODING_CHAR_SIZE 2 /*字符编码字节长度常数*/
#elif defined(_M_OS_LINUX)
    typedef uint32 *string;
    typedef uint32 wchar;
#   define ENCODING_CHAR_SIZE 4
#else
    typedef uint8 *string;
    typedef uint8 wchar;
#   define ENCODING_CHAR_SIZE 1
#endif //

#ifdef _M_UNICODE
#   define T(x) L##x
#   define t(x) L##x
#else
#   define T(x) x
#   define t(x) x
#   ifdef ENCODING_CHAR_SIZE
#       undef ENCODING_CHAR_SIZE
#       define ENCODING_CHAR_SIZE 1 /*字符编码字节长度常数*/
#   endif
#endif

#ifdef _M_M64
    // 指针大小
#   define PTR_SIZE sizeof(ptr)
    // 平台化有符号整数
    typedef int64 nint;
    // 平台化无符号整数
    typedef uint64 nuint;
#elif _M_M32
    // 指针大小
#   define PTR_SIZE sizeof(ptr)
    // 平台化有符号整数
    typedef int32 nint;
    // 平台化无符号整数
    typedef uint32 nuint;
#endif // 

// 指针转为平台化无符号整数值
#define PtrToNUInt(x) ((nuint)(x))
// 平台化无符号整数值转为指针
#define NUIntToPtr(x) ((ptr)(x))
// 指针到结构体
#define PtrToStruct(p, sut) ((sut)(p))

#define alias_struct(name) typedef struct _##name s##name, name
#define impl_struct(name) struct _##name

#define alias_union(name) typedef union _##name s##name, name
#define impl_union(name) union _##name

// 基础结构体
#define def_struct(name)                  \
    typedef struct _##name s##name, name; \
    struct _##name

// 基础共用体
#define def_union(name)                    \
    typedef union _##name u##name, name; \
    union _##name

//基础结构体，定义多个名称
#define def_structs(name, ...)                         \
    typedef struct _##name s##name, name, __VA_ARGS__; \
    struct _##name

// 基础共用体，定义多个名称
#define def_unions(name, ...)                         \
    typedef union _##name u##name, name, __VA_ARGS__; \
    union _##name

// 基础指针结构体
#define defp_struct(name)                    \
    typedef struct _##name s##name, *name; \
    struct _##name

// 基础指针共用体
#define defp_union(name)                    \
    typedef union _##name u##name, *name; \
    union _##name


#define def_enum(name)                    \
    typedef enum _##name e##name, name; \
    enum _##name

#define size_struct(name) sizeof(s##name)
#define size_union(name) sizeof(u##name)

#define CL_CALL __cdecl    // C语言调用模式
#define STD_CALL __stdcall // 通用调用模式

#define STDAPI(type) __declspec(dllexport) type __stdcall // 标准调用方式
#define CAPI(type) __declspec(dllexport) type __cdecl    // C语言调用方式

#define defp_func(name, ret, ...) typedef ret (*name)(__VA_ARGS__) // 定义有返回值函数类型
#define defp_action(name, ...) typedef void (*name)(__VA_ARGS__)   // 定义无返回值函数类型

#define def_func(name, ret, ...) ret (*name)(__VA_ARGS__) // 定义有返回值函数指针
#define def_action(name, ...) void (*name)(__VA_ARGS__)   // 定义无返回值函数指针

#define nameof(x) T(#x) // 将标识符转为名称

// 可变参数支持
typedef byte *varg_list; // 可变参数列表
#ifdef _M_M64
#define __VARG_SIZEOF_(type) ((sizeof(type) + 7) & ~7)
#elif _M_M32
#define __VARG_SIZEOF_(type) ((sizeof(type) + 3) & ~3)
#endif // _64BIT_

#define varg_init(ap, v) (ap = (byte *)&v + __VARG_SIZEOF_(v))                               // 初始化可变参数
#define varg_next(ap, type) (*(type *)((ap += __VARG_SIZEOF_(type)) - __VARG_SIZEOF_(type))) // 获取下一个可变参数
#define varg_free(ap) (ap = null)                                                            // 可变参数结束

#ifdef __cplusplus
}
#endif // __cplusplus

#endif //! _H_TYPEDEF_H_
